package com.ygqh.baby.service.impl;

import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.Message;
import com.ygqh.baby.ao.OrderStatus;
import com.ygqh.baby.ao.OrderType;
import com.ygqh.baby.ao.PromotionType;
import com.ygqh.baby.handler.SingleGiftHandler;
import com.ygqh.baby.model.ActivityGiveawayModel;
import com.ygqh.baby.model.ActivitySingleGift;
import com.ygqh.baby.model.PromotionBo;
import com.ygqh.baby.model.YgPtSkuInfo;
import com.ygqh.baby.po.*;
import com.ygqh.baby.redis.RedisDao;
import com.ygqh.baby.service.*;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.ExceptionUtil;
import com.ygqh.baby.utils.JsonUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author guohao add @2017-03-28 各种短期活动
 */
@Service
public class YgSalesPromotionServiceImpl implements YgSalesPromotionService {

    protected final Logger logger = Logger.getLogger(this.getClass());
    @Autowired
    private YgSkuService YgSkuService;
    @Autowired
    private YgProductService ygProductService;
    @Autowired
    private YgProductImagesService ygProductImagesService;
    @Autowired
    private YgStockService ygStockService;
    @Autowired
    private YgOrderLogService ygOrderLogService;
    @Autowired
    private RedisDao redisDao;
    @Autowired
    private YgOrderService ygOrderService;
    private static List<String> activityKey = new ArrayList<String>();

    {
        activityKey.add("all");
    }

    @Override
    public void activityForManZeng(List<YgOrderDetail> details, List<YgStock> stockList, String sourceCode,
                                   BigDecimal totalPrice, String userName, OrderType orderType) {
        if (!OrderType.GroupBuying.equals(orderType)) {
            ActivityGiveawayModel activity = this.checkActivity(sourceCode, totalPrice);
            if (activity != null) {
                this.addManZeng(activity, details, stockList, sourceCode, totalPrice, userName);
            }
        }
    }

    private ActivityGiveawayModel checkActivity(String sourceCode, BigDecimal totalPrice) {
        ActivityGiveawayModel bestActivity = null;
        if (StringUtil.isNotBlank(sourceCode)) {
            bestActivity = this.getBestActivity(sourceCode, totalPrice);
        }
        if (bestActivity == null && !sourceCode.equals("all")) {
            bestActivity = this.getBestActivity("all", totalPrice);
        }
        return bestActivity;
    }

    private ActivityGiveawayModel getBestActivity(String sourceCode, BigDecimal totalPrice) {
        List<ActivityGiveawayModel> activityList = this.getActivityList(sourceCode);
        if (!CollectionUtils.isEmpty(activityList)) {
            List<ActivityGiveawayModel> collect = activityList.stream()
                    .sorted(Comparator.comparing(ActivityGiveawayModel::getPayPrice).reversed())
                    .collect(Collectors.toList());
            for (ActivityGiveawayModel m : collect) {
                if (m.isValid() && totalPrice.compareTo(m.getPayPrice()) >= 0) {
                    return m;
                }
            }
        }
        return null;

    }

    /**
     * 获取活动
     *
     * @param sourceCode 入参
     * @return ActivityGiveawayModel 返回类型
     * @throws
     * @Title: getActivity
     * @author （guohao）
     * @date 2017年7月25日 上午10:15:07
     * @version V1.0
     */
    private ActivityGiveawayModel getActivity(String sourceCode) {
        if (StringUtil.isNotBlank(sourceCode)) {
            String str = redisDao.get("giveaway_" + sourceCode);
            if (StringUtil.isNotBlank(str)) {
                return JsonUtils.toObject(str, ActivityGiveawayModel.class);
            }
        }

        return null;
    }

    private List<ActivityGiveawayModel> getActivityList(String sourceCode) {
        if (StringUtil.isNotBlank(sourceCode)) {
            String str = redisDao.get("giveaway_" + sourceCode);
            if (StringUtil.isNotBlank(str)) {
                List<ActivityGiveawayModel> list = JSON.parseArray(str, ActivityGiveawayModel.class);
                return list;
            }
        }

        return null;
    }

    private void addManZeng(ActivityGiveawayModel activity, List<YgOrderDetail> details, List<YgStock> stockList,
                            String sourceCode, BigDecimal totalPrice, String userName) {
        sourceCode = activity.getSourceCode();
        String skuCode = activity.getSkuCode();
        Date startDate = activity.getStartDate();
        Date endDate = activity.getEndDate();
        Long giveCount = activity.getGiveCount();
        Long giveNumber = activity.getGiveNumber();
        BigDecimal mzPrice = activity.getPayPrice();
        Date currentDate = new Date();

        Long diffDayes = DateConvertUtils.diffDayes(startDate, endDate);
        int validTime = (diffDayes.intValue() + 1) * 24 * 60 * 60 * 1000;
        String giveawayAmount_key = "giveCount_" + sourceCode + "_" + skuCode;

        // 适用所有订单
        // if ("all".equals(activity.getSourceCode())) {
        // validTime = 1 * 24 * 60 * 60 * 1000;
        // sourceCode = userName + "_" + DateConvertUtils.format(new Date());
        // }

        if (currentDate.before(endDate) && currentDate.after(startDate)) {
            String giveawayAmount = redisDao.get(giveawayAmount_key);
            Long amount = 0L;
            if (StringUtil.isNotBlank(giveawayAmount)) {
                amount = Long.parseLong(giveawayAmount);
            }

            if (amount < giveCount || giveCount == 0) {

                Boolean checkStock = this.checkStock(skuCode, activity.getCheckStock(), amount);
                if (checkStock) {
                    this.doAdd(skuCode, details, stockList, mzPrice, giveNumber);
                    amount++;
                    redisDao.set(giveawayAmount_key, amount + "", validTime);
                } else {
                    ygOrderLogService.addOrderLog(details.get(0).getOrderId(), OrderStatus.WaitingPay, "addManZeng",
                            "赠品库存不足," + sourceCode);
                }
            }
        }

    }

    private void doAdd(String skuCode, List<YgOrderDetail> details, List<YgStock> stockList, BigDecimal mzPrice,
                       Long giveNumber) {

        YgSku sku = YgSkuService.findBySkuCode(skuCode, PromotionType.Ordinary);
        YgProduct product = ygProductService.findById(sku.getProductId());
        YgProductImages image = ygProductImagesService.findMainImgByProductId(sku.getProductId());
        YgOrderDetail detail = new YgOrderDetail();
        detail.setOrderId(details.get(0).getOrderId());

        detail.setProductName(product.getProductName());
        detail.setPromotionType(PromotionType.ManZeng);
        detail.setQuantity(giveNumber);
        detail.setSize(sku.getSizeName());
        detail.setSupplierId(product.getSupplierId());
        detail.setSkuCode(sku.getSkuCode());
        detail.setProductId(sku.getProductId());
        detail.setSkuId(sku.getId());
        detail.setUnitName(product.getUnitName());
        detail.setImageUrl(image.getImagePath());
        detail.setShortName(product.getShortName());
        detail.setProductCode(product.getProductCode());
        detail.setRemark("ManZeng," + mzPrice.toString());
        detail.setShareRate(BigDecimal.ZERO);
        detail.setForeverRate(BigDecimal.ZERO);

        detail.setNewCustomDisPrice(BigDecimal.ZERO);
        detail.setRealPrice(BigDecimal.ZERO);
        detail.setSalePrice(BigDecimal.ZERO);
        detail.setMjDisPrice(BigDecimal.ZERO);
        detail.setBmDisPrice(BigDecimal.ZERO);
        detail.setPackDisPrice(BigDecimal.ZERO);
        detail.setVipDisPrice(BigDecimal.ZERO);
        detail.setYhqDisPrice(BigDecimal.ZERO);
        detail.setExpressPrice(BigDecimal.ZERO);
        detail.setAccountPrice(BigDecimal.ZERO);
        detail.setCostPrice(sku.getCostPrice());

        PromotionBo promotionBo = new PromotionBo();
        promotionBo.setType(PromotionType.ManZeng);
        promotionBo.setLimitPrice(mzPrice);
        detail.setPromotionRemark(JSON.toJSONString(promotionBo));

        details.add(detail);

        YgStock stock = new YgStock();
        stock.setSkuCode(sku.getSkuCode());
        stock.setAmount(giveNumber);
        stockList.add(stock);

    }

    private Boolean checkStock(String skuCode, Boolean checkStock, Long buyCount) {
        checkStock = checkStock == null ? true : checkStock;
        if (checkStock) {
            YgStock stock = ygStockService.findBySkuCode(skuCode);
            if (stock.getAmount() < buyCount) {
                return false;
            }
        }
        return true;
    }

    @Override
    public Message checkHeXiao(List<YgPtSkuInfo> skuList, Long userId) {
        String skustr = redisDao.get("Action_Product");
        Boolean hasHeXiaoSku = false;

        if (StringUtil.isNotBlank(skustr)) {
            String[] skus = skustr.split(",");
            List<String> skuIdList = Arrays.asList(skus);
            for (YgPtSkuInfo sku : skuList) {
                if (skuIdList.contains(sku.getSkuId().toString())) {
                    hasHeXiaoSku = true;
                }
            }
            if (hasHeXiaoSku) {
                Boolean hasHeXiaoOrder = ygOrderService.hasHeXiaoOrder(userId);
                if (hasHeXiaoOrder || skuList.size() > 1 || skuList.get(0).getQuantity() > 1) {
                    return Message.error("不要贪心哦，一个用户只能买一件。", null);
                }
            }

        }
        return Message.success(hasHeXiaoSku);
    }

    @Override
    public int removeCacheByAll(Long orderId, String userName) {
        // DOTO 注意 ：原始 需求已跳整,再次使用时 确认下需求是否满足
        ActivityGiveawayModel activity = this.getActivity("all");
        if (activity != null) {
            String skuCode = activity.getSkuCode();
            YgOrder order = ygOrderService.findOrderDetailByOrderId(orderId);
            for (YgOrderDetail od : order.getOrderDetail()) {
                if (od.getSkuCode().equals(skuCode) && od.getSalePrice().intValue() == 0) {
                    String key = "giveCount_" + userName + "_" + DateConvertUtils.format(order.getCreateTime());
                    redisDao.set(key, 0 + "", 0);
                }
            }
        }
        return 1;
    }

    @Autowired
    private SingleGiftHandler singleGiftHandler;

    @Override
    public void activityForSingleGift(List<YgOrderDetail> details, List<YgStock> stockList, String sourceCode,
                                      BigDecimal totalPrice, String userName, OrderType orderType) {
        try {
            List<ActivitySingleGift> useAbleList = singleGiftHandler.getUseAbleList(sourceCode);
            for (ActivitySingleGift singleGift : useAbleList) {

                boolean meetSingleGiftRule = meetSingleGiftRule(details, singleGift);
                if (meetSingleGiftRule) {
                    Boolean checkStock = checkStock(singleGift.getGiftSkuCode(), singleGift.getCheckStock(), singleGift.getGiveCount());
                    if (checkStock) {
                        this.doAdd(singleGift.getGiftSkuCode(), details, stockList, totalPrice, singleGift.getGiveCount());
                    } else {
                        ygOrderLogService.addOrderLog(details.get(0).getOrderId(), OrderStatus.WaitingPay, "activityForSingleGift",
                                "赠品库存不足," + sourceCode);
                    }
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("userName=" + userName + ";sourceCode=" + sourceCode + ";" + ExceptionUtil.getExceptionMsg(e));
        }

    }


    private boolean meetSingleGiftRule(List<YgOrderDetail> details, ActivitySingleGift singleGift) {
        List<String> split = Arrays.asList(singleGift.getSourceSkuCodes().split(","));
        Long buyCount = details.stream().filter(od -> split.contains(od.getSkuCode()) && !od.getPromotionType().equals(PromotionType.ManZeng)
                && !od.getPromotionType().equals(PromotionType.JiaJiaGou))
                .map(YgOrderDetail::getQuantity).reduce(0L, (a, b) -> a + b);
        return buyCount >= singleGift.getBuyCount();
    }

    private Boolean hasSingleGiftSku(List<YgOrderDetail> details, List<String> sourceSkuCodes) {
        for (YgOrderDetail detail : details) {
            if (sourceSkuCodes.contains(detail.getSkuCode())) {
                return true;
            }
        }
        return false;
    }

}
